<template>
    <div class="role-manager">
        <div class="query-form">    
            <!-- 查询区域 -->
            <el-form ref="form" :inline="true" :model="queryForm">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="queryForm.roleName" placeholder="请输入角色名称"/>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleQuery">查询</el-button>
                    <el-button @click="handleReset('form')">重置</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div class="base-table">
            <!-- 列表区域 -->
            <div class="action">
                <el-button type="primary" @click="handleAdd" v-has="'role-create'">新增</el-button>
            </div>
            <el-table :data="roleList">
                <el-table-column
                    v-for="item in columns"
                    :key="item.prop"
                    :prop="item.prop" 
                    :label="item.label" 
                    :width="item.width"
                    :formatter="item.formatter"
                >
                </el-table-column>
                <el-table-column label="操作" width="280">
                    <template #default="scope">
                        <el-button size="small" @click="handleEdit(scope.row)" v-has="'role-edit'"
                            >编辑</el-button
                        >
                        <el-button size="small" type="primary" @click="handleOpenPermisson(scope.row)" v-has="'role-set-permission'"
                            >设置权限</el-button
                        >
                        <el-button type="danger" size="small" @click="handleDel(scope.row._id)" v-has="'role-delete'"
                            >删除</el-button
                        >
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination 
                class="pagination"
                background
                layout="prev, pager, next" 
                :total="pager.total || 1"
                :page-size="pager.pageSize"
                @current-change="handleCurrentChange"
                />
        </div>
        <el-dialog :title="action=='create'?'角色新增':'角色编辑'" v-model="showModel" width="40%" @close="handleClose">
            <el-form ref="dialogForm" :model="roleForm" label-width="80px" :rules="rules">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" />
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input type="textarea" :rows="2" v-model="roleForm.remark" placeholder="请输入备注" />
                </el-form-item>
            </el-form>
            <template #footer>
                    <div class="dialog-footer">
                        <el-button @click="handleClose">取消</el-button>
                        <el-button type="primary" @click="handleSubmit">确定</el-button>
                    </div>
                </template>
        </el-dialog>

        <!-- 权限弹框 -->
        <el-dialog title="权限设置" v-model="showPermisson" width="40%">
            <el-form label-width="80px" >
                <el-form-item label="角色名称">
                    {{ curRoleName }}
                </el-form-item>
                <el-form-item label="选择权限">
                    <el-tree
                        ref="tree"
                        :data="menuList"
                        show-checkbox
                        node-key="_id"
                        default-expand-all
                        :props="{ children: 'children', label: 'menuName' }"
                    >

                    </el-tree>
                </el-form-item>
            </el-form>
            <template #footer>
                    <div class="dialog-footer">
                        <el-button @click="showPermisson=false">取消</el-button>
                        <el-button type="primary" @click="handlePermissionSubmit">确定</el-button>
                    </div>
                </template>
        </el-dialog>
    </div>
</template>
  
<script>
import utils from '@/utils/utils.js'
import { pa } from 'element-plus/es/locale/index.mjs';
export default {
    name: 'role',
    data() {
        return {
            queryForm: {
                roleName: '',
            },
            columns: [
                {
                    label: '角色名称',
                    prop: 'roleName',
                },
                {
                    label: '备注',
                    prop: 'remark',
                },
                {
                    label: '权限列表',
                    prop: 'permissionList',
                    formatter: (row, column, value)=> {
                        let names = []
                        let list = value.halfCheckedKeys || [];
                        list.map(key => {
                            let name = this.actionMap[key]
                            if(key && name)names.push(name)
                        })
                        return names.join(',')
                    }

                },
                {
                    label: '创建时间',
                    prop: 'createTime',
                    width: 170,
                    formatter(row, column, value) {
                        return utils.formateDate(new Date(value));
                    }
                },
                {
                    label: '更新时间',
                    prop: 'updateTime',
                    width: 170,
                    formatter(row, column, value) {
                        return utils.formateDate(new Date(value));
                    }
                },
            ],   
            roleList: [],
            pager: {
                total: 0,
                pageNum: 1,
                pageSize: 10,
            },
            showModel: false,
            action: 'create',
            roleForm: {},
            rules: {
                roleName: [
                    {
                        required: true,
                        message: '请输入角色名称',
                        trigger: 'blur'
                    },
                    {
                        min: 2,
                        max: 10,
                        message: '长度在 2 到 10 个字符',
                        trigger: 'blur'
                    }
                ]
            },
            // 权限展示
            showPermisson: false,
            curRoleId: "",
            curRoleName: "",
            menuList: [],
            // 菜单映射表
            actionMap:{},
        };
    },
    mounted() {
        this.getRoleList();
        this.getMenuList();
    },
    methods: {
        // 角色列表初始化
        async getRoleList() {
            try {
                let { list, page } = await this.$api.getRoleList({
                    ...this.queryForm,
                    ...this.pager
                });
                this.roleList = list;
                this.pager.total = page.total;
            } catch (error) {
                throw new Error(error);
            }

        },
        // 菜单列表初始化
        async getMenuList() {
            try {
                let list = await this.$api.getMenuList();
                this.menuList = list;
                this.getActionMap(list)
            } catch (error) {
                throw new Error(error);
            }
        },
        // 表单查询
        handleQuery() {
            this.getRoleList();
        },
        // 表单重置
        handleReset(form) {
            this.$refs[form].resetFields()
        },
        // 新增角色
        handleAdd() {
            this.action = 'create';
            this.showModel = true;
        },
        // 编辑角色
        handleEdit(row) {
            this.action = 'edit';
            this.showModel = true;
            this.$nextTick(() => {
                this.roleForm = {
                    _id: row._id,
                    roleName: row.roleName,
                    remark: row.remark
                };
            })

        },
        // 删除角色
        async handleDel(_id) {
            await this.$api.roleOperate({ _id, action: 'delete' });
            this.$message.success('删除成功');
            this.getRoleList();
        },
        // 关闭弹窗
        handleClose() {
            this.showModel = false;
            this.handleReset('dialogForm');
        },
        // 角色提交
        handleSubmit() {
            this.$refs.dialogForm.validate(async (valid) => {
                if (valid) {
                    let { roleForm, action } = this;
                    let params = { ...roleForm, action };
                    let res = await this.$api.roleOperate(params)
                    if (res) {
                        this.showModel = false;
                        if (action == 'edit') {
                            this.$message.success('编辑成功');
                        } else {
                            this.$message.success('新增成功');
                        }
                        this.handleReset('dialogForm');
                        this.getRoleList();
                    }
                } else {
                    return false;
                }
            });
        },
        // 分页
        handleCurrentChange(current) {
            this.pager.pageNum = current;
            this.getRoleList();
        },
        // 打开权限弹框
        handleOpenPermisson(row) {
            // 获取当前角色的各个属性
            this.curRoleId = row._id;
            this.curRoleName = row.roleName;
            this.showPermisson = true;
            // 解构出checkedKeys，即有权限的按钮
            // 在本次设计中，checkedKeys即全选只包含没有子菜单的菜单或按钮，halfCheckedKeys包含有子菜单的菜单
            // 这样可以避免在某个菜单下新增按钮时，如果这个菜单在checkedKeys中，可能会导致新增的按钮直接被选中
            let { checkedKeys } = row.permissionList
            // 将需要勾选的选项勾选
            setTimeout(() => {
                this.$refs.tree.setCheckedKeys(checkedKeys);
            })
        },
        async handlePermissionSubmit() {
            // 在本次设计中，checkedKeys即全选只包含没有子菜单的菜单或按钮，halfCheckedKeys包含有子菜单的菜单
            // 这样可以避免在某个菜单下新增按钮时，如果这个菜单在checkedKeys中，可能会导致新增的按钮直接被选中
            let nodes = this.$refs.tree.getCheckedNodes();
            let halfKeys = this.$refs.tree.getHalfCheckedKeys();
            let checkedKeys = [];
            let parentKeys = [];
            nodes.map(node => {
                if(!node.children) {
                    checkedKeys.push(node._id);
                } else {
                    parentKeys.push(node._id);
                }
            });
            let params = {
                _id: this.curRoleId,
                permissionList: {
                    checkedKeys,
                    halfCheckedKeys: parentKeys.concat(halfKeys)
                    
                }
            }
            await this.$api.updatePermission(params);
            this.showPermisson = false;
            this.$message.success('权限设置成功');
            this.getRoleList();
        },
        //  将菜单key值转换成文字
        getActionMap(list) {
            let actionMap = {}
            const deep = (arr) => {
                while (arr.length) {
                    let item = arr.pop()
                    if (item.children && item.action) {
                        actionMap[item._id] = item.menuName;
                    }
                    if (item.children && !item.action) {
                        deep(item.children)
                    }
                }
            }
            // 由于上面对数据进行pop处理，数据格式变了，所以这里要对传入的参数重新序列化一下
            // 避免arr.pop()将原对象操作
            deep(JSON.parse(JSON.stringify(list)))
            this.actionMap = actionMap
        }
    }
}
</script>
  
<style lang="scss">
.role-manager {
    .query-form {
        margin-bottom: 20px;
    }
    .base-table{
        border-radius: 5px 5px 0px 0px;
        background: #ffffff;
        padding: 20px;
        border-bottom: 1px solid #e4e8e8;
        .pagination{
            margin-top: 20px;
            display: flex;
            justify-content: flex-end; /* 靠右对齐 */
        }
    }
}
</style>
  